package com.jayqqaa12.service.system;

import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
import java.util.stream.Collectors;

import com.jayqqaa12.jbase.jfinal.auto.BaseService;
import com.jayqqaa12.jbase.sdk.util.ShiroExt;
import com.jayqqaa12.model.Tree;
import com.jayqqaa12.model.TreeKit;
import com.jayqqaa12.model.ZTree;
import com.jayqqaa12.model.system.Res;
import com.jayqqaa12.model.system.RoleRes;
import com.jayqqaa12.shiro.ShiroCache;
import com.jayqqaa12.shiro.ShiroInterceptor;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;

/**
 * Generated by Jbase.
 */
public class ResService extends BaseService<Res> {


    public static ResService me() {
        return me(ResService.class);
    }


    public List<Res> list(Integer pid) {
        List<Res> counts = dao.find(sql("system_res.getChildSize"));
        List<Res> list = null;
        if (pid == null) list = dao.findAllByWhere("where pid is null ");
        else list = dao.findAllByWhere("where pid= ?", pid);

        list.forEach(r -> {
            List<Res> ret = counts.stream().filter(res -> res.getPid() == r.getId()).collect(Collectors.toList());
            if (!ret.isEmpty()) r.put("childSize", ret.get(0).get("c"));
        });

        return list;
    }

    public List<String> getUrls() {
        return TreeKit.getAttr(dao, sql("system_res.getUrls"), "url");
    }

    public List<String> getAuthUrls() {
        return getUrls().stream().filter(url -> new ShiroExt().hasPermission(url)).collect(Collectors.toList());
    }


    public List<Res> getChild(Integer id, Integer type) {
        ShiroExt ext = new ShiroExt();
        List<Res> list = null;

        if (type == null) return dao.findAllByWhere("where pid =?", id);
        else if (id == null && type == Res.TYPE_MEUE)
            list = dao.findAllByWhere(" where  pid is null and type =? order by seq ", type);
        else if (id == null && type == Res.TYPE_PERMISSION) list = dao.findAllByWhere("where pid is null order by seq");
        else if (type == Res.TYPE_MEUE) list = dao.findAllByWhere(" where  pid =? and type =? order by seq ", id, type);
        else if (type == Res.TYPE_PERMISSION) list = dao.findAllByWhere(" where  pid =? order by seq  ", id);

        if (id == null) return list;
        else if (Res.TYPE_PERMISSION == type) return list;
        else {
            ListIterator<Res> itor = list.listIterator();
            while (itor.hasNext()) {
                Res r = itor.next();
                if (r.getStr("url") == null) continue;
                if (!ext.hasPermission(r.getStr("url"))) {
                    itor.remove();
                }
            }
        }

        return list;
    }

    /***
     * 批量授权 会先删除所有权限再授权
     *
     * @param roleId
     * @param resIds
     * @return
     */
    public boolean batchGrant(Object roleId, String resIds) {

        boolean result = RoleRes.dao.deleteByWhere("where role_id=?", roleId);

        if (StrKit.notBlank(resIds)) result = batchAdd(roleId, resIds);
        ShiroCache.clearAuthorizationInfoAll();

        return result;
    }

    public boolean grant(int roleId, String resIds) {
        boolean result = false;
        if (StrKit.notBlank(resIds)) result = batchAdd(roleId, resIds);
        ShiroCache.clearAuthorizationInfoAll();
        return result;
    }

    public boolean batchAdd(Object roleId, String resIds) {

        List<RoleRes> list = Arrays.asList(resIds.split(","))
                .stream().map(resId -> {
                    return new RoleRes().setRoleId(roleId).setResId(resId);
                })
                .collect(Collectors.toList());

        Db.batchSave(list, list.size());
        return true;
    }

    /**
     * 转化为 easyui Tree 对象
     *
     * @param type
     * @return
     */
    public List<Tree> getTree(Integer pid, int type, Integer passId) {

        return getChild(pid, type).stream()
                .filter(res -> !res.getId().equals(passId))
                .map(res -> {
                    Tree tree = new Tree(res.getId(), res.getPid(), res.getName(), res.getIconCls(), res.getAttrs(), false);
                    tree.children = getTree(res.getId(), type, passId);
                    if (!tree.children.isEmpty()) tree.changeState();
                    return tree;
                }).collect(Collectors.toList());
    }

    public List<ZTree> getZTree() {
        return super.findAll().stream().map(r -> {
            ZTree zt = new ZTree(r.getId(), r.getName(), r.getPid());
            if (zt.id == 0) zt.setDisCheck(true);
            return zt;
        }).collect(Collectors.toList());
    }

    public boolean delete(String id) {

        removeAuthorization();
        return TreeKit.deleteByIdAndPid(dao, id);
    }

    @Override
    public boolean save(Res res) {

        boolean result = false;

        if (res.getId() == null) {
            result = res.save();
            if(result) grant(1, res.getId() + "");

        } else result = res.update();

        removeAuthorization();

        return result;
    }

    private void removeAuthorization() {
        ShiroCache.clearAuthorizationInfoAll();
        ShiroInterceptor.updateUrls();
    }
}
